function Rule() { 
	this.data = null;
	this.update = [ ];
};

Rule.prototype.getName = function() {
	return "rule";
};

Rule.prototype.addUpdateListener = function(func) {
	if (!$.isFunction(func)) {
		return -1;
	}
	if (!$.isArray(this.update)) {
		this.update = [];
	}
	this.update.push(func);
};

Rule.prototype.updateView = function() {
	var that = this;
	$(this.update).each(function(index, update) {
		if ($.isFunction(update)) {
			update(that);
		}
	});
};

Rule.prototype.loadFromDb = function (callback) {
	var that = this;
	chrome.storage.local.get("rules", function(data) {
		that.data = data.rules;
		that.updateView();
		$.isFunction(callback) && callback(that);
		console.log("LoadFromDb succ");
	});
};

Rule.prototype.saveToDb = function(data, callback) {
	var that = this;
	if (!data || !data.length) {
		return -1;
	}
	chrome.storage.local.set({
		"rules": data
	}, function() {
		that.data = data;
		that.updateView();
		$.isFunction(callback) && callback();
		chrome.extension.sendRequest(
			{
				"cmd": "load_rule"
			}, 
			function(response) {}
		);
	});
};

Rule.prototype.saveRule = function(rule) {
	var rules = this.data;
	if (!$.isArray(rules)) {
		rules = [];
	}
	for (var i = 0, n = rules.length; i < n; i++) {
		if (rules[i].name == rule.name) {
			rules[i] = rule;
			rule = null;
			break;
		}
	}
	if (rule) {
		rules.push(rule);
	}
	this.saveToDb(rules);
};

Rule.prototype.saveRules = function(rules) {
	if (!rules || !rules.length || rules.length == 0) {
		return;
	}
	for (var i = 0, n = rules.length; i < n; i++) {
		this.saveRule(rules[i]);
	}
}

Rule.prototype.clearRule = function(callback) {
	this.data = [];
	this.saveRule(null); // save to db and reload view
};

Rule.prototype.traverse = function(func) {
	$(this.data).each(function(index, elem) {
		func(elem);
	});
};

Rule.prototype.getRuleByUrl = function(url) {
	var rules = this.data;
	if (!rules || !rules.length) {
		return null;
	}
	for (var i = 0, n = rules.length; i < n; i++) {
		var rule = rules[i];
		if (rule.exc && ((new RegExp(rule.exc).test(url)) || (url.indexOf(rule.exe) >= 0))) {
			break;
		}
		if (rule.inc && ((new RegExp(rule.inc).test(url)) || (url.indexOf(rule.inc) >= 0))) {
			return rule;
		}
	    /* inc is greater than exc */
	}
	return null;
};

Rule.prototype.getFlagByUrl = function(url, name) {
	if (name != "cancel") {
		return null;
	}
	var rules = this.data;
	if (!rules || !rules.length) {
		return null;
	}
	for (var i = 0, n = rules.length; i < n; i++) {
		var rule = rules[i];
		if (rule.inc && ((new RegExp(rule.inc).test(url)) || (url.indexOf(rule.inc) >= 0))) {
			if (rule.cancel) {
				return true;
			}
		}
	}
	return false;
};

Rule.prototype.getData = function() {
	return this.data;
}

Rule.prototype.setData = function(data) {
	// this.data = data;
	this.saveToDb(data);
	// this.updateView();
	return this.data;
}
